package com.tong.cloud.redisson.lock.configure;

import com.tong.cloud.redisson.lock.properties.MultipleServerProperties;
import com.tong.cloud.redisson.lock.properties.RedissonProperties;
import com.tong.cloud.redisson.lock.properties.SingleServerProperties;
import org.redisson.config.*;
import org.redisson.connection.balancer.LoadBalancer;
import org.springframework.util.StringUtils;

public class ServerConfigurationFactory {


    public static void create(Config config, RedissonProperties redissonProperties) {
        switch (redissonProperties.getServerType()) {
            case SINGLE:
                setSingleConfig(config, redissonProperties);
                break;
            case CLUSTER:
                setClusterConfig(config, redissonProperties);
                break;
            case MASTERSLAVE:
                setMasterSlaveConfig(config, redissonProperties);
                break;
            case REPLICATED:
                setReplicatedConfig(config, redissonProperties);
                break;
            case SENTINEL:
                setSentinelConfig(config, redissonProperties);
                break;

        }
    }

    public static void setReplicatedConfig(Config config, RedissonProperties redissonProperties) {
        MultipleServerProperties multipleServerProperties = redissonProperties.getMultipleServerProperties();
        ReplicatedServersConfig replicatedServersConfig = config.useReplicatedServers();
        replicatedServersConfig.setDatabase(multipleServerProperties.getDatabase());
        replicatedServersConfig.setScanInterval(multipleServerProperties.getScanInterval());
        replicatedServersConfig.setSlaveConnectionMinimumIdleSize(multipleServerProperties.getSlaveConnectionMinimumIdleSize());
        replicatedServersConfig.setSlaveConnectionPoolSize(multipleServerProperties.getSlaveConnectionPoolSize());
        replicatedServersConfig.setFailedSlaveReconnectionInterval(multipleServerProperties.getFailedSlaveReconnectionInterval());
        replicatedServersConfig.setFailedSlaveCheckInterval(multipleServerProperties.getFailedSlaveCheckInterval());
        replicatedServersConfig.setMasterConnectionMinimumIdleSize(multipleServerProperties.getMasterConnectionMinimumIdleSize());
        replicatedServersConfig.setMasterConnectionPoolSize(multipleServerProperties.getMasterConnectionPoolSize());
        replicatedServersConfig.setReadMode(multipleServerProperties.getReadMode());
        replicatedServersConfig.setSubscriptionMode(multipleServerProperties.getSubscriptionMode());
        replicatedServersConfig.setSubscriptionConnectionMinimumIdleSize(multipleServerProperties.getSubscriptionConnectionMinimumIdleSize());
        replicatedServersConfig.setSubscriptionConnectionPoolSize(multipleServerProperties.getSubscriptionConnectionPoolSize());
        replicatedServersConfig.setDnsMonitoringInterval(multipleServerProperties.getDnsMonitoringInterval());
        try {
            replicatedServersConfig.setLoadBalancer((LoadBalancer) Class.forName(multipleServerProperties.getLoadBalancer()).newInstance());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        for (String nodeAddress : multipleServerProperties.getNodeAddresses()) {
            replicatedServersConfig.addNodeAddress(prefixAddress(nodeAddress));
        }
        replicatedServersConfig.setClientName(redissonProperties.getClientName());
        replicatedServersConfig.setConnectTimeout(redissonProperties.getConnectTimeout());
        replicatedServersConfig.setIdleConnectionTimeout(redissonProperties.getIdleConnectionTimeout());
        replicatedServersConfig.setKeepAlive(redissonProperties.getKeepAlive());
        replicatedServersConfig.setPassword(redissonProperties.getPassword());
        replicatedServersConfig.setPingConnectionInterval(redissonProperties.getPingConnectionInterval());
        replicatedServersConfig.setRetryAttempts(redissonProperties.getRetryAttempts());
        replicatedServersConfig.setRetryInterval(redissonProperties.getRetryInterval());
        replicatedServersConfig.setSslEnableEndpointIdentification(redissonProperties.getSslEnableEndpointIdentification());
        replicatedServersConfig.setSslKeystore(redissonProperties.getSslKeystore());
        replicatedServersConfig.setSslKeystorePassword(redissonProperties.getSslKeystorePassword());
        replicatedServersConfig.setSslProvider(redissonProperties.getSslProvider());
        replicatedServersConfig.setSslTruststore(redissonProperties.getSslTruststore());
        replicatedServersConfig.setSslTruststorePassword(redissonProperties.getSslTruststorePassword());
        replicatedServersConfig.setSubscriptionsPerConnection(redissonProperties.getSubscriptionsPerConnection());
        replicatedServersConfig.setTcpNoDelay(redissonProperties.getTcpNoDelay());
        replicatedServersConfig.setTimeout(redissonProperties.getTimeout());
    }

    public static void setMasterSlaveConfig(Config config, RedissonProperties redissonProperties) {
        MultipleServerProperties multipleServerProperties = redissonProperties.getMultipleServerProperties();
        MasterSlaveServersConfig masterSlaveServersConfig = config.useMasterSlaveServers();
        masterSlaveServersConfig.setDatabase(multipleServerProperties.getDatabase());
        masterSlaveServersConfig.setSlaveConnectionMinimumIdleSize(multipleServerProperties.getSlaveConnectionMinimumIdleSize());
        masterSlaveServersConfig.setSlaveConnectionPoolSize(multipleServerProperties.getSlaveConnectionPoolSize());
        masterSlaveServersConfig.setFailedSlaveReconnectionInterval(multipleServerProperties.getFailedSlaveReconnectionInterval());
        masterSlaveServersConfig.setFailedSlaveCheckInterval(multipleServerProperties.getFailedSlaveCheckInterval());
        masterSlaveServersConfig.setMasterConnectionMinimumIdleSize(multipleServerProperties.getMasterConnectionMinimumIdleSize());
        masterSlaveServersConfig.setMasterConnectionPoolSize(multipleServerProperties.getMasterConnectionPoolSize());
        masterSlaveServersConfig.setReadMode(multipleServerProperties.getReadMode());
        masterSlaveServersConfig.setSubscriptionMode(multipleServerProperties.getSubscriptionMode());
        masterSlaveServersConfig.setSubscriptionConnectionMinimumIdleSize(multipleServerProperties.getSubscriptionConnectionMinimumIdleSize());
        masterSlaveServersConfig.setSubscriptionConnectionPoolSize(multipleServerProperties.getSubscriptionConnectionPoolSize());
        masterSlaveServersConfig.setDnsMonitoringInterval(multipleServerProperties.getDnsMonitoringInterval());
        try {
            masterSlaveServersConfig.setLoadBalancer((LoadBalancer) Class.forName(multipleServerProperties.getLoadBalancer()).newInstance());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        int index = 0;
        for (String nodeAddress : multipleServerProperties.getNodeAddresses()) {
            if (index++ == 0) {
                masterSlaveServersConfig.setMasterAddress(prefixAddress(nodeAddress));
            } else {
                masterSlaveServersConfig.addSlaveAddress(prefixAddress(nodeAddress));
            }
        }
        masterSlaveServersConfig.setClientName(redissonProperties.getClientName());
        masterSlaveServersConfig.setConnectTimeout(redissonProperties.getConnectTimeout());
        masterSlaveServersConfig.setIdleConnectionTimeout(redissonProperties.getIdleConnectionTimeout());
        masterSlaveServersConfig.setKeepAlive(redissonProperties.getKeepAlive());
        masterSlaveServersConfig.setPassword(redissonProperties.getPassword());
        masterSlaveServersConfig.setPingConnectionInterval(redissonProperties.getPingConnectionInterval());
        masterSlaveServersConfig.setRetryAttempts(redissonProperties.getRetryAttempts());
        masterSlaveServersConfig.setRetryInterval(redissonProperties.getRetryInterval());
        masterSlaveServersConfig.setSslEnableEndpointIdentification(redissonProperties.getSslEnableEndpointIdentification());
        masterSlaveServersConfig.setSslKeystore(redissonProperties.getSslKeystore());
        masterSlaveServersConfig.setSslKeystorePassword(redissonProperties.getSslKeystorePassword());
        masterSlaveServersConfig.setSslProvider(redissonProperties.getSslProvider());
        masterSlaveServersConfig.setSslTruststore(redissonProperties.getSslTruststore());
        masterSlaveServersConfig.setSslTruststorePassword(redissonProperties.getSslTruststorePassword());
        masterSlaveServersConfig.setSubscriptionsPerConnection(redissonProperties.getSubscriptionsPerConnection());
        masterSlaveServersConfig.setTcpNoDelay(redissonProperties.getTcpNoDelay());
        masterSlaveServersConfig.setTimeout(redissonProperties.getTimeout());
    }

    public static void setClusterConfig(Config config, RedissonProperties redissonProperties) {
        MultipleServerProperties multipleServerProperties = redissonProperties.getMultipleServerProperties();
        ClusterServersConfig clusterServersConfig = config.useClusterServers();
        clusterServersConfig.setScanInterval(multipleServerProperties.getScanInterval());
        clusterServersConfig.setSlaveConnectionMinimumIdleSize(multipleServerProperties.getSlaveConnectionMinimumIdleSize());
        clusterServersConfig.setSlaveConnectionPoolSize(multipleServerProperties.getSlaveConnectionPoolSize());
        clusterServersConfig.setFailedSlaveReconnectionInterval(multipleServerProperties.getFailedSlaveReconnectionInterval());
        clusterServersConfig.setFailedSlaveCheckInterval(multipleServerProperties.getFailedSlaveCheckInterval());
        clusterServersConfig.setMasterConnectionMinimumIdleSize(multipleServerProperties.getMasterConnectionMinimumIdleSize());
        clusterServersConfig.setMasterConnectionPoolSize(multipleServerProperties.getMasterConnectionPoolSize());
        clusterServersConfig.setReadMode(multipleServerProperties.getReadMode());
        clusterServersConfig.setSubscriptionMode(multipleServerProperties.getSubscriptionMode());
        clusterServersConfig.setSubscriptionConnectionMinimumIdleSize(multipleServerProperties.getSubscriptionConnectionMinimumIdleSize());
        clusterServersConfig.setSubscriptionConnectionPoolSize(multipleServerProperties.getSubscriptionConnectionPoolSize());
        clusterServersConfig.setDnsMonitoringInterval(multipleServerProperties.getDnsMonitoringInterval());
        try {
            clusterServersConfig.setLoadBalancer((LoadBalancer) Class.forName(multipleServerProperties.getLoadBalancer()).newInstance());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        for (String nodeAddress : multipleServerProperties.getNodeAddresses()) {
            clusterServersConfig.addNodeAddress(prefixAddress(nodeAddress));
        }
        clusterServersConfig.setClientName(redissonProperties.getClientName());
        clusterServersConfig.setConnectTimeout(redissonProperties.getConnectTimeout());
        clusterServersConfig.setIdleConnectionTimeout(redissonProperties.getIdleConnectionTimeout());
        clusterServersConfig.setKeepAlive(redissonProperties.getKeepAlive());
        clusterServersConfig.setPassword(redissonProperties.getPassword());
        clusterServersConfig.setPingConnectionInterval(redissonProperties.getPingConnectionInterval());
        clusterServersConfig.setRetryAttempts(redissonProperties.getRetryAttempts());
        clusterServersConfig.setRetryInterval(redissonProperties.getRetryInterval());
        clusterServersConfig.setSslEnableEndpointIdentification(redissonProperties.getSslEnableEndpointIdentification());
        clusterServersConfig.setSslKeystore(redissonProperties.getSslKeystore());
        clusterServersConfig.setSslKeystorePassword(redissonProperties.getSslKeystorePassword());
        clusterServersConfig.setSslProvider(redissonProperties.getSslProvider());
        clusterServersConfig.setSslTruststore(redissonProperties.getSslTruststore());
        clusterServersConfig.setSslTruststorePassword(redissonProperties.getSslTruststorePassword());
        clusterServersConfig.setSubscriptionsPerConnection(redissonProperties.getSubscriptionsPerConnection());
        clusterServersConfig.setTcpNoDelay(redissonProperties.getTcpNoDelay());
        clusterServersConfig.setTimeout(redissonProperties.getTimeout());
    }

    public static void setSentinelConfig(Config config, RedissonProperties redissonProperties) {
        MultipleServerProperties multipleServerProperties = redissonProperties.getMultipleServerProperties();
        SentinelServersConfig sentinelServersConfig = config.useSentinelServers();
        sentinelServersConfig.setDatabase(multipleServerProperties.getDatabase());
        sentinelServersConfig.setMasterName(multipleServerProperties.getMasterName());
        sentinelServersConfig.setScanInterval(multipleServerProperties.getScanInterval());
        sentinelServersConfig.setSlaveConnectionMinimumIdleSize(multipleServerProperties.getSlaveConnectionMinimumIdleSize());
        sentinelServersConfig.setSlaveConnectionPoolSize(multipleServerProperties.getSlaveConnectionPoolSize());
        sentinelServersConfig.setFailedSlaveReconnectionInterval(multipleServerProperties.getFailedSlaveReconnectionInterval());
        sentinelServersConfig.setFailedSlaveCheckInterval(multipleServerProperties.getFailedSlaveCheckInterval());
        sentinelServersConfig.setMasterConnectionMinimumIdleSize(multipleServerProperties.getMasterConnectionMinimumIdleSize());
        sentinelServersConfig.setMasterConnectionPoolSize(multipleServerProperties.getMasterConnectionPoolSize());
        sentinelServersConfig.setReadMode(multipleServerProperties.getReadMode());
        sentinelServersConfig.setSubscriptionMode(multipleServerProperties.getSubscriptionMode());
        sentinelServersConfig.setSubscriptionConnectionMinimumIdleSize(multipleServerProperties.getSubscriptionConnectionMinimumIdleSize());
        sentinelServersConfig.setSubscriptionConnectionPoolSize(multipleServerProperties.getSubscriptionConnectionPoolSize());
        sentinelServersConfig.setDnsMonitoringInterval(multipleServerProperties.getDnsMonitoringInterval());
        try {
            sentinelServersConfig.setLoadBalancer((LoadBalancer) Class.forName(multipleServerProperties.getLoadBalancer()).newInstance());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        for (String nodeAddress : multipleServerProperties.getNodeAddresses()) {
            sentinelServersConfig.addSentinelAddress(prefixAddress(nodeAddress));
        }
        sentinelServersConfig.setClientName(redissonProperties.getClientName());
        sentinelServersConfig.setConnectTimeout(redissonProperties.getConnectTimeout());
        sentinelServersConfig.setIdleConnectionTimeout(redissonProperties.getIdleConnectionTimeout());
        sentinelServersConfig.setKeepAlive(redissonProperties.getKeepAlive());
        sentinelServersConfig.setPassword(redissonProperties.getPassword());
        sentinelServersConfig.setPingConnectionInterval(redissonProperties.getPingConnectionInterval());
        sentinelServersConfig.setRetryAttempts(redissonProperties.getRetryAttempts());
        sentinelServersConfig.setRetryInterval(redissonProperties.getRetryInterval());
        sentinelServersConfig.setSslEnableEndpointIdentification(redissonProperties.getSslEnableEndpointIdentification());
        sentinelServersConfig.setSslKeystore(redissonProperties.getSslKeystore());
        sentinelServersConfig.setSslKeystorePassword(redissonProperties.getSslKeystorePassword());
        sentinelServersConfig.setSslProvider(redissonProperties.getSslProvider());
        sentinelServersConfig.setSslTruststore(redissonProperties.getSslTruststore());
        sentinelServersConfig.setSslTruststorePassword(redissonProperties.getSslTruststorePassword());
        sentinelServersConfig.setSubscriptionsPerConnection(redissonProperties.getSubscriptionsPerConnection());
        sentinelServersConfig.setTcpNoDelay(redissonProperties.getTcpNoDelay());
        sentinelServersConfig.setTimeout(redissonProperties.getTimeout());
    }


    public static void setSingleConfig(Config config, RedissonProperties redissonProperties) {
        SingleServerConfig singleServerConfig = config.useSingleServer();
        SingleServerProperties properties = redissonProperties.getSingleServerProperties();
        singleServerConfig.setAddress(prefixAddress(properties.getAddress()));
        singleServerConfig.setConnectionMinimumIdleSize(properties.getConnectionMinimumIdleSize());
        singleServerConfig.setConnectionPoolSize(properties.getConnectionPoolSize());
        singleServerConfig.setDatabase(properties.getDatabase());
        singleServerConfig.setDnsMonitoringInterval(properties.getDnsMonitoringInterval());
        singleServerConfig.setSubscriptionConnectionMinimumIdleSize(properties.getSubscriptionConnectionMinimumIdleSize());
        singleServerConfig.setSubscriptionConnectionPoolSize(properties.getSubscriptionConnectionPoolSize());
        singleServerConfig.setClientName(redissonProperties.getClientName());
        singleServerConfig.setConnectTimeout(redissonProperties.getConnectTimeout());
        singleServerConfig.setIdleConnectionTimeout(redissonProperties.getIdleConnectionTimeout());
        singleServerConfig.setKeepAlive(redissonProperties.getKeepAlive());
        singleServerConfig.setPassword(redissonProperties.getPassword());
        singleServerConfig.setPingConnectionInterval(redissonProperties.getPingConnectionInterval());
        singleServerConfig.setRetryAttempts(redissonProperties.getRetryAttempts());
        singleServerConfig.setRetryInterval(redissonProperties.getRetryInterval());
        singleServerConfig.setSslEnableEndpointIdentification(redissonProperties.getSslEnableEndpointIdentification());
        singleServerConfig.setSslKeystore(redissonProperties.getSslKeystore());
        singleServerConfig.setSslKeystorePassword(redissonProperties.getSslKeystorePassword());
        singleServerConfig.setSslProvider(redissonProperties.getSslProvider());
        singleServerConfig.setSslTruststore(redissonProperties.getSslTruststore());
        singleServerConfig.setSslTruststorePassword(redissonProperties.getSslTruststorePassword());
        singleServerConfig.setSubscriptionsPerConnection(redissonProperties.getSubscriptionsPerConnection());
        singleServerConfig.setTcpNoDelay(redissonProperties.getTcpNoDelay());
        singleServerConfig.setTimeout(redissonProperties.getTimeout());
    }

    private static String prefixAddress(String address) {
        if (!StringUtils.isEmpty(address) && !address.startsWith("redis")) {
            return "redis://" + address;
        }
        return address;
    }
}
